package com.idopartx.phonelightning.ui.home.notification

import android.annotation.SuppressLint
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.dotools.umlibrary.UMPostUtils
import com.idopartx.phonelightning.R
import com.idopartx.phonelightning.common.Constant
import com.idopartx.phonelightning.databinding.ActivityNotifyLightningBinding
import com.idopartx.phonelightning.databinding.DialogExitBinding
import com.idopartx.phonelightning.databinding.HeaderEidtNotificationBinding
import com.idopartx.phonelightning.entity.AppInfo
import com.idopartx.phonelightning.entity.LightNightVo
import com.idopartx.phonelightning.entity.NotifyLightningCache
import com.idopartx.phonelightning.thread.LightningThread
import com.idopartx.phonelightning.ui.adapter.AppListAdapter
import com.idopartx.phonelightning.ui.base.BaseActivity
import com.idopartx.phonelightning.utils.BitmapUtils
import com.idopartx.phonelightning.utils.DialogUtil
import com.idopartx.phonelightning.viewmodel.NotifyLightingViewModel
import com.tencent.mmkv.MMKV
import com.wuhenzhizao.titlebar.widget.CommonTitleBar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*


class NotifyLightningActivity : BaseActivity<ActivityNotifyLightningBinding>() {

    private val viewModel: NotifyLightingViewModel by lazy {
        ViewModelProvider(this).get(NotifyLightingViewModel::class.java)
    }

    private val notifyLightningCache: NotifyLightningCache? by lazy {
        MMKV.defaultMMKV()
            .decodeParcelable(Constant.MMKV_SAVE_NOTIFY_LIGHTNING, NotifyLightningCache::class.java)
    }

    private val appListAdapter: AppListAdapter by lazy {
        AppListAdapter()
    }

    private var packageInfoList: MutableList<PackageInfo>? = null
    private var applicationInfoList: MutableList<AppInfo>? = null
    private var pm: PackageManager? = null

    private var thread: LightningThread? = null

    override fun initLayoutResId(): Int {
        return R.layout.activity_notify_lightning
    }

    private val headerBinding: HeaderEidtNotificationBinding by lazy {
        DataBindingUtil.inflate(
            LayoutInflater.from(this),
            R.layout.header_eidt_notification,
            binding.rvRoot,
            false
        )
    }

    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        viewModel.lightNightLiveData.value =
            if (notifyLightningCache?.lightNightList != null && notifyLightningCache?.lightNightList!!.isNotEmpty()) notifyLightningCache?.lightNightList else arrayListOf(
                LightNightVo(500, 500)
            )

        viewModel.periodLiveData.value = notifyLightningCache?.showTimes ?: 2
        headerBinding.tvTitle.text = "闪烁周期${viewModel.periodLiveData.value}"

        viewModel.settingAllLiveData.value = notifyLightningCache?.isAll ?: true

        headerBinding.viewModel = viewModel

        binding.viewTitleBar.setListener { v, action, _ ->
            when (action) {
                CommonTitleBar.ACTION_RIGHT_TEXT -> {
                    if (v is TextView) {
                        saveData()
                    }
                }
                CommonTitleBar.ACTION_LEFT_BUTTON -> {
                    onBackPressedSupport()
                }
            }
        }

        headerBinding.sbPeriod.setProgress((viewModel.periodLiveData.value ?: 2).toFloat())

        headerBinding.sbLight.setProgress(
            (viewModel.lightNightLiveData.value?.get(0)?.light ?: 500).toFloat() / 10
        )
        headerBinding.sbNight.setProgress(
            (viewModel.lightNightLiveData.value?.get(0)?.night ?: 500).toFloat() / 10
        )


        headerBinding.sbPeriod.onProgressChangedListener =
            object : com.idopartx.phonelightning.widget.KBubbleSeekBar.OnProgressChangedListener {
                override fun onProgressChanged(
                    bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                    progress: Int,
                    progressFloat: Float,
                    fromUser: Boolean
                ) {
                    headerBinding.tvTitle.text = "闪烁周期${progress}"
                }

                override fun getProgressOnActionUp(
                    bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                    progress: Int,
                    progressFloat: Float
                ) {
                }

                override fun getProgressOnFinally(
                    bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                    progress: Int,
                    progressFloat: Float,
                    fromUser: Boolean
                ) {
                    headerBinding.tvTitle.text = "闪烁周期${progress}"
                    viewModel.periodLiveData.value = progress
                    thread = null
                    thread?.stopThread()
                    thread = LightningThread(
                        applicationContext,
                        viewModel.lightNightLiveData.value,
                        viewModel.periodLiveData.value ?: 2
                    )
                    thread?.start()
                }
            }

        headerBinding.sbLight.onProgressChangedListener =
            getOnProgressChangedListener("亮%dms", headerBinding.tvLightNum)
        headerBinding.tvLightNum.text = String.format("亮%dms", headerBinding.sbLight.progress * 10)

        headerBinding.sbNight.onProgressChangedListener =
            getOnProgressChangedListener("灭%dms", headerBinding.tvNightNum)
        headerBinding.tvNightNum.text = String.format("灭%dms", headerBinding.sbNight.progress * 10)

        binding.rvRoot.adapter = appListAdapter
        appListAdapter.addHeaderView(headerBinding.root)

        lifecycleScope.launch {
            applicationInfoList = getAllAppNames()

            if (viewModel.settingAllLiveData.value == true) {
                appListAdapter.setList(arrayListOf())
            } else {
                applicationInfoList?.forEach { all ->
                    notifyLightningCache?.selectAppList?.forEach { select ->
                        if (all.packageName == select) {
                            all.isOpen = true
                        }
                    }
                }

                appListAdapter.setList(applicationInfoList)
            }
        }

        viewModel.settingAllLiveData.observe(this, {
            if (it) {
                appListAdapter.setList(arrayListOf())
            } else {
                appListAdapter.setList(applicationInfoList)
            }
        })

    }

    override fun onBackPressedSupport() {
        if (checkEdit()) {
            finish()
            return
        }


        val dialogBinding = DataBindingUtil.inflate<DialogExitBinding>(
            LayoutInflater.from(this),
            R.layout.dialog_exit,
            null,
            false
        )
        val dialog = DialogUtil.getDialog(
            this,
            dialogBinding.root,
            DialogUtil.DialogGravity.CENTER
        )

        dialogBinding.tvCancel.setOnClickListener {
            dialog.dismiss()
        }

        dialogBinding.tvConfirm.setOnClickListener {
            saveData()

        }
        dialog.show()
    }

    private fun saveData() {
        val cache = NotifyLightningCache(
            viewModel.periodLiveData.value,
            viewModel.lightNightLiveData.value,
            viewModel.settingAllLiveData.value,
            appListAdapter.getSelectList()
        )


        val eventMap = HashMap<String, String>()
        appListAdapter.getSelectList().forEachIndexed { index, s ->
            eventMap["appname$index"] = s
        }
        UMPostUtils.onEventMap(
            this,
            "noti_save_click_parameter_appname",
            eventMap
        )


        MMKV.defaultMMKV().encode(Constant.MMKV_SAVE_NOTIFY_LIGHTNING, cache)
        finish()
    }


    private fun checkEdit(): Boolean {
        if (notifyLightningCache == null) {
            return false
        }
        if (notifyLightningCache?.showTimes != viewModel.periodLiveData.value) {
            return false
        }

        if (notifyLightningCache?.lightNightList != viewModel.lightNightLiveData.value) {
            return false
        }


        return true
    }


    private fun getOnProgressChangedListener(
        stringFormat: String,
        textView: TextView
    ): com.idopartx.phonelightning.widget.KBubbleSeekBar.OnProgressChangedListener {

        return object :
            com.idopartx.phonelightning.widget.KBubbleSeekBar.OnProgressChangedListener {
            override fun onProgressChanged(
                bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                progress: Int,
                progressFloat: Float,
                fromUser: Boolean
            ) {
                textView.text = String.format(stringFormat, progress * 10)
            }

            override fun getProgressOnActionUp(
                bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                progress: Int,
                progressFloat: Float
            ) {
            }

            override fun getProgressOnFinally(
                bubbleSeekBar: com.idopartx.phonelightning.widget.KBubbleSeekBar?,
                progress: Int,
                progressFloat: Float,
                fromUser: Boolean
            ) {

                viewModel.lightNightLiveData.value =
                    arrayListOf(
                        LightNightVo(
                            headerBinding.sbLight.progress * 10,
                            headerBinding.sbNight.progress * 10
                        )
                    )

                thread = null
                thread?.stopThread()
                thread = LightningThread(
                    applicationContext,
                    viewModel.lightNightLiveData.value,
                    viewModel.periodLiveData.value ?: 2
                )
                thread?.start()
                textView.text = String.format(stringFormat, progress * 10)
            }

        }
    }


    private suspend fun getAllAppNames(): MutableList<AppInfo> {
        val appInfoList = arrayListOf<AppInfo>()
        withContext(Dispatchers.IO) {
            pm = packageManager
            // 获取到所有安装了的应用程序的信息，包括那些卸载了的，但没有清除数据的应用程序
            packageInfoList =
                pm?.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
            val list =
                pm?.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
            Collections.sort(list, ApplicationInfo.DisplayNameComparator(pm));// 排序
            appInfoList.clear()

            list?.forEach {
                val x = (Math.random() * 100).toInt()
                val y = (Math.random() * 100).toInt()

                if (it.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
                    appInfoList.add(getAppInfo(pm!!, it, x, y));//如果非系统应用，则添加至appList
                } //系统程序
            }
        }
        return appInfoList
    }

    private fun getAppInfo(
        pm: PackageManager,
        app: ApplicationInfo,
        a: Int,
        b: Int
    ): AppInfo {
        return AppInfo(
            app.loadLabel(pm).toString(),
            "",
            BitmapUtils.drawableToBitmap(app.loadIcon(pm)),
            app.packageName,
            a,
            b,
            false
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        thread?.stopThread()
        thread = null
    }
}